using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;

namespace Prospectus
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        private GraphicsDeviceManager graphics;
        private SpriteBatch spriteBatch;
        
        public SpriteFont font;
        private Texture2D itemBkgd;
        
        private TileLayer tileLayer;

        public Camera camera = new Camera();

        public int ScreenWidth;
        public int ScreenHeight;

        bool showStats = false;
        private bool lockCamera = true;

        #region Constructor

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            graphics.PreferredBackBufferWidth = 800;
            graphics.PreferredBackBufferHeight = 600;

            this.IsMouseVisible = true;
            this.Window.Title = "Prospectus Alpha 1.0";
        }

        #endregion

        #region Loading Code

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            ScreenWidth = GraphicsDevice.Viewport.Width;
            ScreenHeight = GraphicsDevice.Viewport.Height;

            // Fonts
            font = Content.Load<SpriteFont>("Fonts/hudFont");

            // Item Bkgd HUD
            itemBkgd = Content.Load<Texture2D>("Misc/itemBkgd");

            LoadMap(true);
        }

        private void LoadMap(bool isNewGame)
        {
            // Load the map.
            //string mapPath = "Content/Saved Games/mapData.txt";
            //using (Stream fileStream = TitleContainer.OpenStream(mapPath))
            if (isNewGame)
                tileLayer = new TileLayer(true, this);
            else
                tileLayer.LoadContent();
        }

        #endregion

        #region Update Code

        protected override void Update(GameTime gameTime)
        {
            InputManager.Update();
            // Allows the game to exit
            if (InputManager.IsKeyDown(Keys.Escape)) { this.Exit(); }

            if (InputManager.IsKeyPress(Keys.F1))
            {
                if (showStats) { showStats = false; }
                else { showStats = true; }
            }

            if (InputManager.IsKeyPress(Keys.PageUp))
                camera.Zoom += 0.1f;
            if (InputManager.IsKeyPress(Keys.PageDown))
                camera.Zoom -= 0.1f;

            if (!lockCamera)
            {
                if (InputManager.IsKeyDown(Keys.Up))
                    camera.Position.Y -= 15;
                if (InputManager.IsKeyDown(Keys.Down))
                    camera.Position.Y += 15;
                if (InputManager.IsKeyDown(Keys.Left))
                    camera.Position.X -= 15;
                if (InputManager.IsKeyDown(Keys.Right))
                    camera.Position.X += 15;
            }
            
            

            if (InputManager.IsKeyPress(Keys.F))
                lockCamera = !lockCamera;

            if (lockCamera)
            {
                tileLayer.Update(gameTime, camera);
                camera.LockToTarget(tileLayer.Player, ScreenWidth, ScreenHeight);
            }

            camera.ClampToArea(
                tileLayer.WidthInPixels - ScreenWidth,
                tileLayer.HeightInPixels - ScreenHeight);

            if (tileLayer.Player.gameWon)
                LoadMap(false);
                        
            base.Update(gameTime);
        }

        #endregion

        #region Draw Region

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            spriteBatch.Begin(
                SpriteSortMode.Deferred,
                BlendState.AlphaBlend,
                null,
                DepthStencilState.Default,
                RasterizerState.CullNone,
                null,
                camera.TransformMatrix);

            tileLayer.Draw(spriteBatch, camera);

            DrawHUD(spriteBatch);

            if (showStats)
            {
                DrawStats(spriteBatch);
            }

            spriteBatch.End();

            base.Draw(gameTime);
        }

        private void DrawHUD(SpriteBatch spriteBatch)
        {
            Rectangle titleSafeArea = GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X + camera.Position.X, titleSafeArea.Y + camera.Position.Y);
            Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
                                         titleSafeArea.Y + titleSafeArea.Height / 2.0f);

            string xPos = "X Block: " + Engine.ConvertVectorToCell(new Vector2(
                tileLayer.Player.Position.X + tileLayer.Player.texture.Width / 2,
                tileLayer.Player.Position.Y + tileLayer.Player.texture.Height / 2)).X.ToString();
            
            float textHeight = font.MeasureString(xPos).Y;

            spriteBatch.Draw(
                itemBkgd,
                hudLocation + new Vector2(titleSafeArea.Width - 42, 10.0f),
                new Color(48, 48, 48, 100));

            if (tileLayer.Player.Inventory.Count > 0)
            {
                spriteBatch.Draw(
                    tileLayer.Player.Inventory[tileLayer.Player.selectedItem].Texture,
                    hudLocation + new Vector2(titleSafeArea.Width - 42 + 16, 26.0f),
                    tileLayer.Player.Inventory[tileLayer.Player.selectedItem].SourceRectangle,
                    Color.White,
                    0.0f,
                    new Vector2(8, 8),
                    1.0f,
                    SpriteEffects.None,
                    0.0f);
            }
        }

        private void DrawStats(SpriteBatch spriteBatch)
        {
            Rectangle titleSafeArea = GraphicsDevice.Viewport.TitleSafeArea;
            Vector2 hudLocation = new Vector2(titleSafeArea.X + camera.Position.X, titleSafeArea.Y + camera.Position.Y);
            Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
                                         titleSafeArea.Y + titleSafeArea.Height / 2.0f);

            int middleTile = tileLayer.Width / 2;
            Point playerCell = Engine.ConvertVectorToCell(new Vector2(
                tileLayer.Player.Position.X + tileLayer.Player.texture.Width / 2,
                tileLayer.Player.Position.Y + tileLayer.Player.texture.Height / 2));
            int playerXPos = 0;
            if (playerCell.X < middleTile)
                playerXPos = -middleTile + playerCell.X;
            else if (playerCell.X > middleTile)
                playerXPos = playerCell.X - middleTile;
            else
                playerXPos = 0;

            string xPos = "X Block: " + playerXPos.ToString();
            string yPos = "Y Block: " + (tileLayer.Height - playerCell.Y).ToString();

            float textHeight = font.MeasureString(xPos).Y;

            spriteBatch.DrawString(
                font,
                xPos,
                hudLocation,
                Color.White);
            
            spriteBatch.DrawString(
                font,
                yPos,
                hudLocation + new Vector2(0.0f, textHeight * 1.2f),
                Color.White);
            spriteBatch.DrawString(
                font,
                "Type: " + tileLayer.GetBlockType(Engine.ConvertVectorToCell(tileLayer.Player.Position)).ToString(),
                hudLocation + new Vector2(titleSafeArea.Width / 2, 0.0f),
                Color.White);
        }

        #endregion
    }
}
